package cn.edu.buaa.treehole.service;

import cn.edu.buaa.treehole.dao.PostDao;
import cn.edu.buaa.treehole.dao.PostTagDao;
import cn.edu.buaa.treehole.dao.exception.DaoException;
import cn.edu.buaa.treehole.pojo.dao.PostDaoInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.*;

@Service
public class PostListService {
    private static final int cacheSize = 128;
    private static final int capacityTimes = 2;


    private final PostDao postDao;
    private final PostTagDao postTagDao;

    @Autowired
    public PostListService(PostDao postDao, PostTagDao postTagDao) {
        this.postDao = postDao;
        this.postTagDao = postTagDao;
    }

    public long getLatest() throws DaoException {
        return postDao.selectMaxPid();
    }

    public long getEarliest() throws DaoException {
        for (int index = 0; true; index++) {
            if (postDao.selectAllPostByPid(index).size() != 0) {
                return index;
            }
        }
    }

    public List<Long> forwardList(long pt, int num) throws DaoException {
        LinkedList<Long> out = new LinkedList<>();

        long max = postDao.selectMaxPid();

        while (num > 0 && pt < max) {
            pt++;
            if (contain(pt)) {
                out.add(pt);
                num--;
            }
        }
        return out;
    }

    public List<Long> backwardList(long pt, int num) throws DaoException {
        LinkedList<Long> out = new LinkedList<>();

        while (num > 0 && pt > 0) {
            pt--;
            if (contain(pt)) {
                out.add(pt);
                num--;
            }
        }
        return out;
    }

    public List<Long> tagList(long pt, int num, long tid) throws DaoException {
        LinkedList<Long> out = new LinkedList<>();

        while (num > 0 && pt >= 0) {
            pt--;
            if (contain(pt)) {
                List<Long> tids = postTagDao.selectAllTidByPid(pt);
                for (long t : tids)
                {
                    if (t == tid) {
                        out.add(pt);
                        num--;
                        break;
                    }
                }
            }
        }
        return out;
    }

    public List<Long> totalList(Set<Long> tids) throws DaoException {
        LinkedList<Long> out = new LinkedList<>();

        long pt = postDao.selectMaxPid() + 1;

        while (pt >= 0) {
            pt--;
            if (contain(pt)) {
                List<Long> post_tids = postTagDao.selectAllTidByPid(pt);
                for (long t : post_tids)
                {
                    if (tids.contains(t)) {
                        out.add(pt);
                        break;
                    }
                }
            }
        }
        return out;
    }

    public List<Long> titleList(long pt, int num, String title) throws DaoException {
        LinkedList<Long> out = new LinkedList<>();

        while (num > 0 && pt > 0) {
            pt--;
            if (contain(pt)) {
                PostDaoInfo postDaoInfo = postDao.selectPostByPid(pt);
                if (postDaoInfo.getTitle().contains(title)) {
                    num--;
                    out.add(pt);
                }
            }
        }
        return out;

    }

    public boolean contain(long pid) throws DaoException {
        return postDao.selectAllPostByPid(pid).size() != 0;
    }
}
